﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using WebService_Newstore.DTO;
using WebService_Newstore.Controller;

namespace WebService_Newstore
{
    // REMARQUE : vous pouvez utiliser la commande Renommer du menu Refactoriser pour changer le nom de classe "Service1" dans le code, le fichier svc et le fichier de configuration.
    public class ServiceBP : IServiceBP
    {
        /// <summary>
        /// cette méthode renvoie la liste des BP générés
        /// </summary>
        /// <param name="dateExp">la date</param>
        /// <returns></returns>
        public List<BPDTO> GenerationBP(DateTime dateExp)
        {
            List<LgCmdDTO> liste_lgcmd = new List<LgCmdDTO>(); // Liste des lignes de commandes
            EmplacementDTO emplacement = new EmplacementDTO();
            bool enteteBPPalette;
            bool ententeBPPicking;
            List<BPDTO> listePB = new List<BPDTO>();

            //Pour chaque commande sélectionnée, on récupère ses lignes de commandes
            foreach (CommandeDTO cmd in ServiceBPController.CommandeToSend(dateExp))
            {

                //On vérifie que la commande ne soit pas cloturée
                if (cmd.statutCmd == 1 || cmd.statutCmd == 0)
                {

                    enteteBPPalette = false;
                    ententeBPPicking = false;
                    bool cmdPreparable = false;
                    int numLigne = 1;

                    //Pour chaque ligne de commande associée à la commande
                    liste_lgcmd = ServiceBPController.GetLgCmdByIDCmd(cmd.idCommande);
                    foreach (LgCmdDTO lg in liste_lgcmd)
                    {
                        
                        bool ligneCmdPreparable = false;
                        bool addbp = true;
                        float qteRestante = lg.qteCmdee - lg.qteLivree; //Contient la quantité restante à préparer
                        float qteAPrep = 0;
                        LgBpDTO lgbpFinal = new LgBpDTO(); //La ligne de BP ajoutée

                        //Si la quantité restante à préparer = 0, on sort de la boucle
                        if (qteRestante > 0)
                        {

                            //On regarde si l'article de la ligne de la commande est en stock
                            foreach (EmplacementDTO emp in ServiceBPController.findEmplacementByArticle(lg.idArticle,lg.code_uniteCmd))
                            {
                                BPDTO bpfinal = new BPDTO(); // Le BP associé a la commande en cours
                                float qteLivree = lg.qteLivree;  //On initialise la quantité livrée avant la génération du BP
                                float stockTheoric = emp.stockQte_Emplacement - ServiceBPController.GetStThEmp(emp.idEmplacement); //Récupération du stock théorique de l'emplacement, cad en prenant compte des reservations

                                //Pour une ligne de commande picking
                                if (emp.isPicking_Emplacement)
                                {
                                    //On vérifie si la ligne de commande est préparable
                                    if (stockTheoric >= 1)
                                    {
                                        ligneCmdPreparable = true;
                                        cmdPreparable = true;

                                        //Vérification BP Existant sinon création BP
                                        foreach (BPDTO bp in ServiceBPController.findBPByIdCmd(cmd.idCommande))
                                        {
                                            if (bp.statutBP == 0 && bp.typeBP == 1)
                                            {
                                                //Entete de BP Existe et est actif pour la commande
                                                ententeBPPicking = true;
                                                bpfinal = bp;
                                            }
                                        }

                                        if (!ententeBPPicking)
                                        {
                                            //Génération entete BP
                                            BPDTO bpAGenere = new BPDTO(0, DateTime.Today, 0, cmd.idCommande, 1, 0);
                                            bpfinal = ServiceBPController.SaveBPDTO(bpAGenere);
                                            ententeBPPicking = true;
                                            //Le statut de la commande passe à en prepa
                                            cmd.statutCmd = 2;
                                            ServiceBPController.SaveCmdDTO(cmd);
                                        }

                                        // On ajoute le BP à la liste a envoyer au client seulement si il n'est pas déjà dedans
                                        if (listePB.Count != 0)
                                        {
                                            foreach (BPDTO bpx in listePB)
                                            {
                                                if (bpx.idBP == bpfinal.idBP)
                                                    addbp = false;
                                            }
                                        }
                                        if(addbp)
                                            listePB.Add(bpfinal);

                                        //Génération de la ligne de BP
                                        
                                        //Calcul de la quantité pour la ligne de BP
                                        if (qteRestante <= stockTheoric && qteRestante != 0)
                                        {
                                            qteAPrep = qteRestante;
                                            qteRestante = 0;
                                            //Reservation du stock de l'emplacement
                                            //emp.stockQte_Emplacement = emp.stockQte_Emplacement - qteAPrep;
                                            //ServiceBPController.SaveEmplacementDTO(emp);

                                            //Il faut mettre à jour le statut de la ligne de commande
                                        }
                                        else if (qteRestante > stockTheoric)
                                        {
                                            qteAPrep = stockTheoric;
                                            qteRestante = qteRestante - qteAPrep;
                                            //Reservation du stock de l'emplacement
                                            //emp.stockQte_Emplacement = 0;
                                            //ServiceBPController.SaveEmplacementDTO(emp);
                                        }

                                        LgBpDTO lgBP = new LgBpDTO(0, bpfinal.idBP, numLigne, lg.idLgCmd, qteAPrep, (float)0, 0, emp.idEmplacement, lg.code_uniteCmd, 0);
                                        lgbpFinal = ServiceBPController.SaveLgBpDTO(lgBP);

                                        numLigne++;

                                        //MAJ de la quantité livrée
                                        //lg.qteLivree = lg.qteLivree + qteAPrep;
                                        //ServiceBPController.SaveLgCmd(lg);
                                    }
                                }
                                //Pour une ligne de commande palette
                                if (!emp.isPicking_Emplacement)
                                {
                                    //On vérifie si la ligne de commande est préparable
                                    if (stockTheoric > 1)
                                    {
                                        ligneCmdPreparable = true;
                                        cmdPreparable = true; // La commande est préparable car elle dispose au moins d'une ligne de commande préparable

                                        //qteRestante = qteRestante - emp.stockQte_Emplacement;

                                        //Vérification BP Existant sinon création BP
                                        foreach (BPDTO bp in ServiceBPController.findBPByIdCmd(cmd.idCommande))
                                        {
                                            if (bp.statutBP == 0 && bp.typeBP == 0)
                                            {
                                                //Entete de BP Existe et est actif pour la commande
                                                enteteBPPalette = true;
                                                bpfinal = bp;
                                            }
                                        }

                                        if (!enteteBPPalette)
                                        {
                                            //Génération entete BP
                                            BPDTO bpAGenere = new BPDTO(0, DateTime.Today, 0, cmd.idCommande, 0, 0);
                                            bpfinal = ServiceBPController.SaveBPDTO(bpAGenere);
                                            enteteBPPalette = true;

                                            //Le statut de la commande passe à en prepa
                                            cmd.statutCmd = 2;
                                            ServiceBPController.SaveCmdDTO(cmd);
                                        }

                                        // On ajoute le BP à la liste a envoyer au client seulement si il n'est pas déjà dedans
                                        if (listePB.Count != 0)
                                        {
                                            foreach (BPDTO bpx in listePB)
                                            {
                                                if (bpx.idBP == bpfinal.idBP)
                                                    addbp = false;
                                            }
                                        }
                                        if (addbp)
                                            listePB.Add(bpfinal);


                                        //Génération de la ligne de BP

                                        //Calcul de la quantité pour la ligne de BP
                                        if (qteRestante <= stockTheoric && qteRestante != 0)
                                        {
                                            qteAPrep = qteRestante;
                                            qteRestante = 0;
                                            //Reservation du stock de l'emplacement
                                            //emp.stockQte_Emplacement = emp.stockQte_Emplacement - qteAPrep;
                                            //ServiceBPController.SaveEmplacementDTO(emp);
                                        }
                                        else if (qteRestante > stockTheoric)
                                        {
                                            qteAPrep = stockTheoric;
                                            qteRestante = qteRestante - qteAPrep;
                                            //Reservation du stock de l'emplacement
                                            //emp.stockQte_Emplacement = 0;
                                            //ServiceBPController.SaveEmplacementDTO(emp);
                                        }

                                        LgBpDTO lgBP = new LgBpDTO(0, bpfinal.idBP, numLigne, lg.idLgCmd, qteAPrep, (float)0, 0, emp.idEmplacement, lg.code_uniteCmd, 0);
                                        lgbpFinal = ServiceBPController.SaveLgBpDTO(lgBP);

                                        numLigne++;

                                        //MAJ de la quantité livrée
                                        //lg.qteLivree = lg.qteLivree + qteAPrep;
                                        //ServiceBPController.SaveLgCmd(lg);
                                    }

                                }
                            }

                            if (!ligneCmdPreparable)
                            {
                                //Si la ligne de commande n'est pas préparable on passe son statut à reliqat;
                                lg.statut = 1;
                                ServiceBPController.SaveLgCmd(lg);
                            }
                        }
                        else
                        {
                            //On passe le statut de la ligne à terminée
                            lg.statut = 3;
                            ServiceBPController.SaveLgCmd(lg);
                        }
                    }

                    if (!cmdPreparable)
                    {
                        //Si la commande n'est pas préparable, on la passe en reliquat
                        cmd.statutCmd = 1;
                        cmd.saveCommande();
                    }
                }
            }
            return listePB;
        }

        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        public List<LgBpDTO> GetLgBPByBP(int idBP)
        {
            return ServiceBPController.GetLgBPByBP(idBP);
        }

        public EmplacementDTO GetEmplacementByID(int idEmp)
        {
            return ServiceBPController.GetEmplacementByID(idEmp);
        }

        public List<BPDTO> GetBPByDate(DateTime startDate, DateTime endDate)
        {
            return ServiceBPController.findBPByDate(startDate, endDate);
        }
    }
}
